/* 
 * File:   main.c
 * Author: Ken
 *
 * Created on 03 January 2014, 22:27
 */

#include <stdio.h>
#include "board.h"
#include "timer.h"
#include "lcd.h"
#include "interrupt.h"

#define TRIGGER     RC3
#define ECHO        RC2
#define LED         RA1

#define TRIS_TRIGGER    TRISC3
#define TRIS_ECHO       TRISC2
#define TRIS_LED        TRISA1

/*
 * 
 */
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);

//__CONFIG(FOSC_INTRC_NOCLKOUT & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF & LVP_OFF);
//__CONFIG(BOR4V_BOR40V & WRT_OFF);

float distance = 0;
float time_val = 0;
bool has_echo = false;
bool has_timeout = false;

void trigger_short();
void port_init();

// Ham xu ly ngat khi phat hien canh len hoac canh xuong cua xung Echo va timer1 ngat
void interrupt all()
{
    // neu co ngat
    if(CCP1IF)
    {
        CCP1IF = 0; // Xoa co ngat
        if(ECHO) // Neu la canh len cua xung Echo
        {
            timer1_start(0); // Start timer1 (Gia tri thanh cap thanh ghi TMR1H:TMR1L bat dau tang tu 0 sau moi 2.667 us
            CCP1CON = 0x04; // dat che do khi chan Echo tu cao xuong thap thi phat ra mot ngat
            LED = 1; // bat LED
        }
        if(!ECHO) // neu la canh xuong cua xung Echo
        {
            timer1_stop(); // Dừng tang timer1
            time_val = timer1_get(); // Doc gia tri trong cạp thanh ghi TMR1H:TMR1L
//             Gia tri do chinh la do rong xung Echo, lay gia tri nay nhan voi 2.667 roi chia cho 58
//             ra khoang cach tinh the cm(chia cho 148 thi tinh ra inch)
            distance = (time_val * 2.6667)/58; 
            
            // Bat co da hoan thanh do xuong chan ECho
            has_echo = true;

            // bat co bao khong bi timeout
            has_timeout = false;
            LED = 0;
        }
    }

    // neu timerout (Sau 65535*2.667us = 174.8 ms thi timeout)
    if(timer1_is_timeout())
    {
        timer1_reset_irs_flag(); // Reset timer1
        has_echo = true; // Bat co bao da hoan thanh do xung Echo
        has_timeout = true; // bat co bao da bi timeout
        distance = -99; // Do khoang cach loi
    }
}
int main(int argc, char** argv)
{
    uint8_t str[16] = {0}; // tao chuoi hien thi ket qua tren LCD
    port_init();    // Khoi tao port
    isr_global_enable(true); // Cho phep ngat toan cuc
    timer1_init(T1_DIV_8, true); // Khoi tao timer1 voi thoi gian 2.7us tang mot gia tri o tan so 12Mhz
    lcd_init(); // Khoi tao LCD
    lcd_clear(); // Xoa hien thi LCD
    has_echo = false;
    has_timeout = false;
    time_val = 0;
    distance = 0;
    delay_ms(100);
    while(1)
    {
        trigger_short(); // Dua xung rong 10us vao chan Trigger
        has_echo = false;
        while(has_echo == false); // Doi chan Echo tra ve xung co do rong t(us)
        lcd_clear(); // Xoa man hinh LCD
        lcd_gotoxy(0, 0); // Ve vi tri dau dong cua dong 1
        sprintf(str, "Dist: %4.1f cm", distance); // copy du lieu hien thi vao chuoi str
        lcd_puts(str); // hien thi ket qua do khoang cach len LCD

        lcd_gotoxy(0, 1); // Dua con tro ve dau dong cua dong 2
        sprintf(str, "Echo: %4.1f us", time_val * 2.6667); //copy du lieu hien thi vao chuoi str
        lcd_puts(str);// hien thi thoi gian phan hoi tren chan Echo len LCD
        delay_ms(1000); 
        CCP1CON = 0x05; // dat che do cho PIC khi co xung tu thap len cao tai chan Echo thi phat ra mot ngat
    }
    return (0);
}

void trigger_short()
{
    TRIGGER = 1; // Dua xung 
    delay_us(10); // rong 10us
    TRIGGER = 0; // len chan Trigger
}

void port_init()
{
    //OSCCON = 0x75;
    ANSEL = 0x00; // Khoi tao cac chan
    ANSELH = 0x00; // la Vao/Ra so
    TRIS_TRIGGER = 0; // khoi tao chan Trigger la chan output
    TRIS_ECHO = 1; // Khoi tao chan Echo la Input
    TRIS_LED = 0; // cahn Led la output
    LED = 0; // Tat LED

    CCP1CON = 0x00; // Reset bo Capture tren PIC(co chuc nang phat hien canh len/xuong cua xuong)
    CCP1CON = 0x05; // Dat che do khi co xung canh thap len cao thi phat ra mot ngat
    CCP1IF = 0; // Reset co ngat
    CCP1IE = 1; // Cho phep ngat
    //CCP1CON = 0x05; // Capture mode, every rising edg
}
